package org.nudt.common.utils

import org.nudt.common.exception.BadRequestException
import org.springframework.web.multipart.MultipartFile
import java.io.File
import java.util.*


object FileUtil {
    
    const val IMAGE: String = "图片"
    const val TXT: String = "文档"
    const val MUSIC: String = "音乐"
    const val VIDEO: String = "视频"
    const val OTHER: String = "其他"
    
    /**
     * 获取文件的对应扩展名，不带 .
     */
    fun getExtensionName(filename: String?): String? {
        if (!filename.isNullOrEmpty()) {
            val dot = filename.lastIndexOf('.')
            if (dot > -1 && dot < filename.length - 1) {
                return filename.substring(dot + 1)
            }
        }
        return filename
    }
    
    /**
     * 上传文件
     */
    fun upload(file: MultipartFile, filePath: String): File? {
        val filename = file.originalFilename
        filename?.let {
            val ext = getExtensionName(filename)
            if (ext == null) {
                throw BadRequestException("文件格式错误")
            } else {
                val fileName = "${UUID.randomUUID().toString().replace("-", "")}.$ext"
                val path = filePath + fileName
                try {
                    // getCanonicalFile 可解析正确各种路径
                    val dest = File(path).getCanonicalFile()
                    // 检测是否存在目录
                    if (!dest.getParentFile().exists()) {
                        if (!dest.getParentFile().mkdirs()) {
                            throw BadRequestException("have no dir")
                        }
                    }
                    // 文件写入
                    file.transferTo(dest)
                    return dest
                } catch (e: Exception) {
                    throw BadRequestException("上传文件出错")
                }
            }
        }
        return null
    }
    
    fun checkSize(maxSize: Long, size: Long) {
        // 1M
        val len = 1024 * 1024
        if (size > maxSize * len) {
            throw BadRequestException("文件超出规定大小:" + maxSize + "MB")
        }
    }
    
    fun getFileType(type: String): String {
        val documents = "txt doc pdf ppt pps xlsx xls docx"
        val music = "mp3 wav wma mpa ram ra aac aif m4a"
        val video = "avi mpg mpe mpeg asf wmv mov qt rm mp4 flv m4v webm ogv ogg"
        val image = "bmp dib pcp dif wmf gif jpg tif eps psd cdr iff tga pcd mpt png jpeg"
        return if (image.contains(type)) {
            IMAGE
        } else if (documents.contains(type)) {
            TXT
        } else if (music.contains(type)) {
            MUSIC
        } else if (video.contains(type)) {
            VIDEO
        } else {
            OTHER
        }
    }
    
    /**
     * Java文件操作 获取不带扩展名的文件名
     */
    fun getFileNameNoEx(filename: String?): String? {
        if (!filename.isNullOrEmpty()) {
            val dot = filename.lastIndexOf('.')
            if (dot > -1 && dot < filename.length) {
                return filename.substring(0, dot)
            }
        }
        return filename
    }
    
    /**
     * 验证并过滤非法的文件名
     * @param fileNameToVerify 文件名
     * @return 文件名
     */
    fun verifyFilename(fileNameToVerify: String): String {
        // 过滤掉特殊字符
        var fileName = fileNameToVerify
        fileName = fileName.replace("[\\\\/:*?\"<>|~\\s]".toRegex(), "")
        
        // 去掉文件名开头和结尾的空格和点
        fileName = fileName.trim { it <= ' ' }.replace("^[. ]+|[. ]+$".toRegex(), "")
        
        // 不允许文件名超过255（在Mac和Linux中）或260（在Windows中）个字符
        var maxFileNameLength = 255
        if (System.getProperty("os.name").startsWith("Windows")) {
            maxFileNameLength = 260
        }
        if (fileName.length > maxFileNameLength) {
            fileName = fileName.substring(0, maxFileNameLength)
        }
        
        // 过滤掉控制字符
        fileName = fileName.replace("\\p{Cntrl}".toRegex(), "")
        
        // 过滤掉 ".." 路径
        fileName = fileName.replace("\\.{2,}".toRegex(), "")
        
        // 去掉文件名开头的 ".."
        fileName = fileName.replace("^\\.+/".toRegex(), "")
        
        // 保留文件名中最后一个 "." 字符，过滤掉其他 "."
        fileName = fileName.replace("^(.*)(\\.[^.]*)$".toRegex(), "$1").replace("\\.".toRegex(), "") +
                fileName.replace("^(.*)(\\.[^.]*)$".toRegex(), "$2")
        return fileName
    }
}